package com.jmda.platform.repository.form.action;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jmda.platform.commom.LocalCacheManager;
import com.jmda.platform.commom.SequenceService;
import com.jmda.platform.commom.SpringContextUtil;
import com.jmda.platform.engine.form.event.FormGridDatasRefEvent;
import com.jmda.platform.engine.mybatis.MybatisEngine;
import com.jmda.platform.repository.ResositoryException;
import com.jmda.platform.repository.RespositoryConstant;
import com.jmda.platform.repository.form.model.FormMetadataMapModel;
import com.jmda.platform.repository.form.model.FormMetadataModel;
import com.jmda.platform.repository.form.model.FormModel;
import com.jmda.platform.repository.form.service.FormMetadataMapService;
import com.jmda.platform.repository.form.service.FormMetadataService;
import com.jmda.platform.repository.form.service.FormService;
import com.jmda.platform.repository.form.util.FormMetadateMapCommonMethod;
import com.jmda.platform.repository.metadata.model.MetadataMapModel;
import com.jmda.platform.repository.metadata.service.MetadataService;
import com.jmda.platform.repository.worklist.util.CamelCaseUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;

@Controller
@RequestMapping("/repository/form/metadatamap")
public class FormMetadataMapController {
    @Resource
    FormMetadataService formMetadataService;
    @Resource
    FormService formService;
    @Resource
    FormMetadataMapService formMetadataMapService;
    @Resource
    MetadataService metadataService;
    @Resource
    SequenceService seq;
    @Resource
    MybatisEngine mybatis;
    @Resource
    FormMetadateMapCommonMethod formMetadateMapCommonMethod;

    @RequestMapping(value = "/openFormMeatadataPage", method = {RequestMethod.POST, RequestMethod.GET})
    public String openFormMeatadataPage(String form_id, String formMetadataId, ModelMap map) throws ResositoryException {
        FormMetadataModel formMetadataModel = formMetadataService.getFormMetadataModel(form_id, formMetadataId);
        map.put("form_id", form_id);
        map.put("formMetadataName", formMetadataModel.getName());
        map.put("formMetadataId", formMetadataModel.getId());
        if (formMetadataModel.getType() == RespositoryConstant.SYS_FORM_METADATA_TYPE_SUB) {
            map.put("page_size", formMetadataModel.getPage_size());
            map.put("grid_height", formMetadataModel.getGrid_height());
            map.put("is_master_dataset", "false");
            if (formMetadataModel.getIs_group() == null || formMetadataModel.getIs_group() == false) {
                map.put("is_group", "false");
            } else {
                map.put("is_group", "true");
            }
            map.put("group_field", formMetadataModel.getGroup_field());
            if(formMetadataModel.getIs_detail()==null || formMetadataModel.getIs_detail()==false){
            	map.put("is_detail", "false");
            }else{
            	map.put("is_detail", "true");
            }
            StringBuffer json = new StringBuffer();
            List<Class> list = getAllClassByInterface(FormGridDatasRefEvent.class);
            if(list!=null&&list.size()>0){
            	json.append("[");
            	for (Class class1 : list) {
					try {
			            Class c = Class.forName(class1.getName());
			            Object object = c.newInstance();
			            Method method = c.getMethod("returnName", null);
			            String name = (String) method.invoke(object, null);
			            if(json.length()>1){
							json.append(",['").append(class1.getName()).append("','").append(name).append("']");
						}else{
							json.append("['").append(class1.getName()).append("','").append(name).append("']");
						}
						/*Class<FormGridDatasRefEvent> eventClass = (Class<FormGridDatasRefEvent>) Class.forName(class1.getName());
						FormGridDatasRefEvent event = SpringContextUtil.getBean(eventClass);
						if (event != null) {
							String name = event.returnName();
							if(json.length()>1){
								json.append(",['").append(class1.getName()).append("','").append(name).append("']");
							}
						}*/
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InstantiationException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (NoSuchMethodException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (SecurityException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
            	json.append("]");
            	map.put("ref", json);
            }
        } else {
            map.put("is_group", "false");
            map.put("is_master_dataset", "true");
            map.put("is_detail", "false");
        }
        if(map.get("ref")==null){
        	map.put("ref", "[]");
        }
        return "repository/form/Sys_Repository_Form_Metadata_Map";
    }
    @SuppressWarnings("rawtypes")
	public static List<Class> getAllClassByInterface(Class c){  
        List returnClassList = new ArrayList<Class>();  
        //判断是不是接口,不是接口不作处理  
        if(c.isInterface()){  
            //String packageName = c.getPackage().getName();  //获得当前包名  
            try {  
                List<Class> allClass = getClasses(LocalCacheManager.jmdaPropertiesMap.get("system.column.mapping.package"));//获得当前包以及子包下的所有类  
                  
                //判断是否是一个接口  
                for(int i = 0; i < allClass.size(); i++){  
                    if(c.isAssignableFrom(allClass.get(i))){  
                        if(!c.equals(allClass.get(i))){  
                            returnClassList.add(allClass.get(i));  
                        }  
                    }  
                }  
            } catch (Exception e) {  
                // TODO: handle exception  
            }  
        }  
        return returnClassList;  
    }
    private static List<Class> getClasses(String packageName) throws ClassNotFoundException,IOException{  
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();  
        String path = packageName.replace(".", "/");  
        Enumeration<URL> resources = classLoader.getResources(path);  
        List<File> dirs = new ArrayList<File>();  
        while(resources.hasMoreElements()){  
            URL resource = resources.nextElement();  
            dirs.add(new File(resource.getFile()));  
        }  
        ArrayList<Class> classes = new ArrayList<Class>();  
        for(File directory:dirs){  
            classes.addAll(findClass(directory, packageName));  
        }  
        return classes;  
    }  
      
    private static  List<Class> findClass(File directory, String packageName)   
        throws ClassNotFoundException{  
        List<Class> classes = new ArrayList<Class>();  
        if(!directory.exists()){  
            return classes;  
        }  
        File[] files = directory.listFiles();  
        for(File file:files){  
            if(file.isDirectory()){  
                assert !file.getName().contains(".");  
                classes.addAll(findClass(file, packageName+"."+file.getName()));  
            }else if(file.getName().endsWith(".class")){  
                classes.add(Class.forName(packageName+"."+file.getName().substring(0,file.getName().length()-6)));  
            }  
        }  
        return classes;  
    }  
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/getFormMeatadataJson", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String getFormMeatadataJson(String form_id, String formMetadataId) throws JsonProcessingException, ResositoryException {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> json = new HashMap<String, Object>();
        List<FormMetadataMapModel> list = formMetadataMapService.getFormMetadataMapList(form_id, formMetadataId);
        list = list == null ? new ArrayList<FormMetadataMapModel>() : list;
        //兼容之前版本缺少字段类型
        for (FormMetadataMapModel formMetadataMapModel : list) {
            if (formMetadataMapModel.getColumn_type() == null || "".equalsIgnoreCase(formMetadataMapModel.getColumn_type().trim())) {
                formMetadataMapModel.setColumn_type("db");
            }
        }
        if (list != null) {
            Collections.sort(list, new Comparator() {
                @Override
                public int compare(Object o1, Object o2) {
                    if (((FormMetadataMapModel) o1).getOrder_index() > ((FormMetadataMapModel) o2).getOrder_index()) {

                        return 1;
                    }
                    if (((FormMetadataMapModel) o1).getOrder_index() == ((FormMetadataMapModel) o2).getOrder_index()) {
                        return 0;
                    }
                    return -1;
                }
            });
        }
        json.put("root", list);
        json.put("total", list == null ? 0 : list.size());


        return mapper.writeValueAsString(json);
    }

    @RequestMapping(value = "/openFormMetadataMapSelectPage", method = {RequestMethod.POST, RequestMethod.GET})
    public String openFormMetadataMapSelectPage(String form_id, String formMetadataId, ModelMap map) {
        map.put("form_id", form_id);
        map.put("formMetadataId", formMetadataId);
        return "repository/form/Sys_Repository_Form_Metadata_Select_Grid";
    }

    @RequestMapping(value = "/openVirtualFormMetadataMapPage", method = {RequestMethod.POST, RequestMethod.GET})
    public String openVirtualFormMetadataMapPage(String form_id, String formMetadataId, ModelMap map) {
        map.put("form_id", form_id);
        map.put("formMetadataId", formMetadataId);
        return "repository/form/Sys_Repository_Form_Metadata_Virtual";
    }

    @RequestMapping(value = "/getFormMetadataMapSelectJsonData", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String getFormMetadataMapSelectJsonData(String form_id, String formMetadataId) throws ResositoryException, JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> json = new HashMap<String, Object>();
        FormMetadataModel formMetadataModel = formMetadataService.getFormMetadataModel(form_id, formMetadataId);
        List<MetadataMapModel> list = metadataService.getMetadataMapListBySql(mybatis.getMapperSql(form_id, RespositoryConstant.WORKLIST_RUNTIME_QUERY_LIST_ID + "_" + formMetadataModel.getId()));
        json.put("root", list);
        json.put("total", list == null ? 0 : list.size());
        return mapper.writeValueAsString(json);
    }

    @RequestMapping(value = "/addFormMetadataMap", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String addFormMetadataMap(String form_id, String formMetadataId, String selectJson) throws ResositoryException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        List<MetadataMapModel> selectFormMetadataMapList = mapper.readValue(selectJson, new TypeReference<ArrayList<MetadataMapModel>>() {
        });
        if (selectFormMetadataMapList != null && selectFormMetadataMapList.size() > 0) {
            FormModel formModel = formService.get(form_id);
            List<FormMetadataModel> formMetadataModellist = formModel.getFormMetadataList();
            for (FormMetadataModel formMetadataModel : formMetadataModellist) {
                // 找到对应的数据集
                if (formMetadataModel.getId().equals(formMetadataId)) {
                    List<FormMetadataMapModel> formMetadataMapList = formMetadataModel.getFormMetadataMapList();
                    formMetadataMapList = formMetadataMapList == null ? new ArrayList<FormMetadataMapModel>() : formMetadataMapList;
                    formMetadataModel.setFormMetadataMapList(formMetadataMapList);
                    // 判断数据集中是否意见存在该字段，不存在创建，存在掠过
                    int i = 0;
                    for (MetadataMapModel metadataMapModel : selectFormMetadataMapList) {
                        boolean isOK = true;
                        for (FormMetadataMapModel formMetadataMapModel : formMetadataMapList) {
                            if (metadataMapModel.getTABLE_COLUMN_TYPE() == null || "".equalsIgnoreCase(metadataMapModel.getTABLE_COLUMN_TYPE().trim()) || "db".equalsIgnoreCase(metadataMapModel.getTABLE_COLUMN_TYPE())) {
                                if (formMetadataMapModel.getColumn_lable().equals(metadataMapModel.getCOLUMN_LABEL()) && formMetadataMapModel.getTable_name().equals(metadataMapModel.getTABLE_NAME())) {
                                    isOK = false;
                                    break;
                                }
                            } else {
                                if (formMetadataMapModel.getColumn_name().equals(metadataMapModel.getCOLUMN_NAME())) {
                                    isOK = false;
                                    break;
                                }
                            }
                        }
                        if (isOK) {
                            FormMetadataMapModel formMetadataMapModel = new FormMetadataMapModel();
                            formMetadataMapModel.setId(seq.getUUID());
                            formMetadataMapModel.setDefault_value("");
                            formMetadataMapModel.setColumn_type((metadataMapModel.getTABLE_COLUMN_TYPE() == null || "".equalsIgnoreCase(metadataMapModel.getTABLE_COLUMN_TYPE().trim())) ? "db" : metadataMapModel.getTABLE_COLUMN_TYPE());
                            formMetadataMapModel.setIndex(0);
                            formMetadataMapModel.setIs_null(true);
                            formMetadataMapModel.setColumn_title(metadataMapModel.getCOLUMN_TITLE());
                            formMetadataMapModel.setUi_type("无");
                            formMetadataMapModel.setUi_length(metadataMapModel.getCOLUMN_LENGTH());
                            formMetadataMapModel.setOrder_index(formService.getFormMetadataMapNextIndex(formMetadataModel)+i);
                            if (formMetadataMapModel.getColumn_type().equalsIgnoreCase("db")) {
                                formMetadataMapModel.setColumn_lable(CamelCaseUtils.toCamelCase(metadataMapModel.getCOLUMN_LABEL()));
                                formMetadataMapModel.setDb_column_lable(metadataMapModel.getCOLUMN_LABEL());
                                formMetadataMapModel.setColumn_name(metadataMapModel.getCOLUMN_LABEL());
                                formMetadataMapModel.setTable_name(metadataMapModel.getTABLE_NAME());
                            } else {
                                formMetadataMapModel.setColumn_lable(metadataMapModel.getCOLUMN_NAME());
                                formMetadataMapModel.setColumn_name(metadataMapModel.getCOLUMN_NAME());
                            }

                            formMetadataMapList.add(formMetadataMapModel);
                        }
                        i = i+1;
                    }
                    formService.store(formModel);
                    break;
                }
            }

        }
        return "ok";
    }

    @RequestMapping(value = "/saveFormMetadataMap", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String saveFormMetadataMap(String form_id, String formMetadataId, String datas, int page_size, int grid_height, Boolean is_group, String group_field,Boolean is_detail) throws ResositoryException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        List<FormMetadataMapModel> modifyMetadataMapList = mapper.readValue(datas, new TypeReference<ArrayList<FormMetadataMapModel>>() {
        });
        //如果做过修改
        if (modifyMetadataMapList != null && modifyMetadataMapList.size() > 0) {
            //从本地文件中读出对应的xml
            FormModel formModel = formService.get(form_id);
            List<FormMetadataModel> formMetadataModellist = formModel.getFormMetadataList();
            for (FormMetadataModel formMetadataModel : formMetadataModellist) {
                // 找到对应的数据集
                if (formMetadataModel.getId().equals(formMetadataId)) {
                    if (formMetadataModel.getType() == RespositoryConstant.SYS_FORM_METADATA_TYPE_SUB) {
                        formMetadataModel.setGrid_height(grid_height);
                        formMetadataModel.setPage_size(page_size);
                        formMetadataModel.setIs_group(is_group);
                        formMetadataModel.setGroup_field(group_field);
                        formMetadataModel.setIs_detail(is_detail);
                    }
                    List<FormMetadataMapModel> formMetadataMapList = formMetadataModel.getFormMetadataMapList();
                    for (FormMetadataMapModel formMetadataMapModel : formMetadataMapList) {
                        // 匹配到修改的字段
                        for (FormMetadataMapModel modifyFormMetadataMapModel : modifyMetadataMapList) {
                            if (formMetadataMapModel.getId().equals(modifyFormMetadataMapModel.getId())) {
                                formMetadataMapModel.setDefault_value(modifyFormMetadataMapModel.getDefault_value());
                                formMetadataMapModel.setIs_null(modifyFormMetadataMapModel.isIs_null());
                                formMetadataMapModel.setColumn_title(modifyFormMetadataMapModel.getColumn_title());
                                formMetadataMapModel.setColumn_lable(modifyFormMetadataMapModel.getColumn_lable());
                                formMetadataMapModel.setUi_type(modifyFormMetadataMapModel.getUi_type());
                                formMetadataMapModel.setUi_param(modifyFormMetadataMapModel.getUi_param());
                                formMetadataMapModel.setColumn_align(modifyFormMetadataMapModel.getColumn_align());
                                formMetadataMapModel.setFormatter(modifyFormMetadataMapModel.getFormatter());
                                formMetadataMapModel.setHidden(modifyFormMetadataMapModel.isHidden());
//                                formMetadataMapModel.setShowdetails(modifyFormMetadataMapModel.isShowdetails());
                                formMetadataMapModel.setSortable(modifyFormMetadataMapModel.isSortable());
                                formMetadataMapModel.setRef_params(modifyFormMetadataMapModel.getRef_params());
                                formMetadataMapModel.setRef_type(modifyFormMetadataMapModel.getRef_type());
                            }
                        }
                    }
                    formService.store(formModel);
                    break;
                }
            }
        } else {
            FormModel formModel = formService.get(form_id);
            List<FormMetadataModel> formMetadataModellist = formModel.getFormMetadataList();
            for (FormMetadataModel formMetadataModel : formMetadataModellist) {
                if (formMetadataModel.getId().equals(formMetadataId)) {
                    if (formMetadataModel.getType() == RespositoryConstant.SYS_FORM_METADATA_TYPE_SUB) {
                        formMetadataModel.setIs_group(is_group);
                        formMetadataModel.setGroup_field(group_field);
                        formMetadataModel.setIs_detail(is_detail);
                        formService.store(formModel);
                        break;
                    }
                }
            }
        }
        return "ok";
    }

    @RequestMapping(value = "/removeFormMetadataMap", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String removeFormMetadataMap(String form_id, String formMetadataId, String ids) throws ResositoryException, IOException {
        String[] idArray = ids.split(",");
        if (idArray != null && idArray.length > 0) {
            FormModel formModel = formService.get(form_id);
            List<FormMetadataModel> formMetadataModellist = formModel.getFormMetadataList();
            for (FormMetadataModel formMetadataModel : formMetadataModellist) {
                // 找到对应的数据集
                if (formMetadataModel.getId().equals(formMetadataId)) {
                    List<FormMetadataMapModel> formMetadataMapList = formMetadataModel.getFormMetadataMapList();
                    List<FormMetadataMapModel> newFormMetadataMapList = new ArrayList<FormMetadataMapModel>();
                    for (FormMetadataMapModel formMetadataMapModel : formMetadataMapList) {
                        boolean isOK = true;
                        // 匹配到删除的列
                        for (int i = 0; i < idArray.length; i++) {
                            if (formMetadataMapModel.getId().equals(idArray[i])) {
                                isOK = false;
                                break;
                            }
                        }
                        if (isOK) {
                            newFormMetadataMapList.add(formMetadataMapModel);
                        }
                    }
                    formMetadataModel.setFormMetadataMapList(newFormMetadataMapList);
                    formService.store(formModel);
                    break;
                }
            }
        }
        return "ok";
    }

    @RequestMapping(value = "/sortGird", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String sortGirdMap(String sourceId, String targetId, String form_id, String form_er_id) {
        return formMetadateMapCommonMethod.formMetadataMapOrder(form_id, form_er_id, sourceId, targetId);
    }
    
    @RequestMapping(value = "/afreshSortFormMetadataMap", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String afreshSortFormMetadataMap(String form_id, String formMetadataId) throws ResositoryException, IOException {
        FormModel formModel = formService.get(form_id);
        List<FormMetadataModel> formMetadataModellist = formModel.getFormMetadataList();
        for (FormMetadataModel formMetadataModel : formMetadataModellist) {
            // 找到对应的数据集
            if (formMetadataModel.getId().equals(formMetadataId)) {
            	int i = 1;
                List<FormMetadataMapModel> formMetadataMapList = formMetadataModel.getFormMetadataMapList();
                for (FormMetadataMapModel formMetadataMapModel : formMetadataMapList) {
                	formMetadataMapModel.setOrder_index(i);
                	i = i +1;
				}
                // 判断数据集中是否意见存在该字段，不存在创建，存在掠过
                formService.store(formModel);
                break;
            }
        }
        return "ok";
    }
}
